{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "isInteractiveWindowMessageCell": true
   },
   "source": [
    "已连接到 env_py38 (Python 3.8.18)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第一章：Pandas DataFrame 基础知识\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       country continent  year  lifeExp       pop   gdpPercap\n",
      "0  Afghanistan      Asia  1952   28.801   8425333  779.445314\n",
      "1  Afghanistan      Asia  1957   30.332   9240934  820.853030\n",
      "2  Afghanistan      Asia  1962   31.997  10267083  853.100710\n",
      "3  Afghanistan      Asia  1967   34.020  11537966  836.197138\n",
      "4  Afghanistan      Asia  1972   36.088  13079460  739.981106\n"
     ]
    }
   ],
   "source": [
    "import pandas\n",
    "df = pandas.read_csv('../data/gapminder.tsv',sep='\\t')\n",
    "print(df.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 读取文件\n",
    "我们通常认为df.read_csv()只能读取.csv文件，实际上它是一个通用函数，这里我们用它来读取.tsv文件，它是一个以“\\t”作为分隔符的文件，我们通过参数sep='\\t'来调整读取方式。那么如果我们没有设置这个参数，它会默认使用“,”作为分隔符，这会让程序抛出一个错误。\n",
    "\n",
    "Python在抛出错误时，会按照调用栈的顺序给出错误信息。调用栈（Call Stack）是程序在执行过程中调用函数或方法时形成的栈结构，它记录了函数调用的顺序和每个函数的执行状态。\n",
    "\n",
    "当程序出现错误时，python会停止执行并生成一个异常对象，然后从调用栈顶部开始，逐层向下回溯，寻找可以处理该异常的try...except块，若没有找到，则将异常信息打印到控制台。\n",
    "\n",
    "示例代码：\n",
    "\n",
    "```python\n",
    "def func_a():\n",
    "    func_b()\n",
    "\n",
    "def func_b():\n",
    "    func_c()\n",
    "\n",
    "def func_c():\n",
    "    1 / 0  # 这里会抛出一个ZeroDivisionError\n",
    "\n",
    "func_a()\n",
    "\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "ZeroDivisionError",
     "evalue": "division by zero",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[2], line 10\u001b[0m\n\u001b[0;32m      7\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc_c\u001b[39m():\n\u001b[0;32m      8\u001b[0m     \u001b[38;5;241m1\u001b[39m \u001b[38;5;241m/\u001b[39m \u001b[38;5;241m0\u001b[39m  \u001b[38;5;66;03m# 这里会抛出一个ZeroDivisionError\u001b[39;00m\n\u001b[1;32m---> 10\u001b[0m \u001b[43mfunc_a\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[1;32mIn[2], line 2\u001b[0m, in \u001b[0;36mfunc_a\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc_a\u001b[39m():\n\u001b[1;32m----> 2\u001b[0m     \u001b[43mfunc_b\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[1;32mIn[2], line 5\u001b[0m, in \u001b[0;36mfunc_b\u001b[1;34m()\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc_b\u001b[39m():\n\u001b[1;32m----> 5\u001b[0m     \u001b[43mfunc_c\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[1;32mIn[2], line 8\u001b[0m, in \u001b[0;36mfunc_c\u001b[1;34m()\u001b[0m\n\u001b[0;32m      7\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc_c\u001b[39m():\n\u001b[1;32m----> 8\u001b[0m     \u001b[38;5;241;43m1\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\n",
      "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero"
     ]
    }
   ],
   "source": [
    "def func_a():\n",
    "    func_b()\n",
    "\n",
    "def func_b():\n",
    "    func_c()\n",
    "\n",
    "def func_c():\n",
    "    1 / 0  # 这里会抛出一个ZeroDivisionError\n",
    "\n",
    "func_a()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n"
     ]
    }
   ],
   "source": [
    "print(type(df))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1704, 6)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap'], dtype='object')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "country       object\n",
      "continent     object\n",
      "year           int64\n",
      "lifeExp      float64\n",
      "pop            int64\n",
      "gdpPercap    float64\n",
      "dtype: object\n",
      "------------------------- \n",
      "\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1704 entries, 0 to 1703\n",
      "Data columns (total 6 columns):\n",
      " #   Column     Non-Null Count  Dtype  \n",
      "---  ------     --------------  -----  \n",
      " 0   country    1704 non-null   object \n",
      " 1   continent  1704 non-null   object \n",
      " 2   year       1704 non-null   int64  \n",
      " 3   lifeExp    1704 non-null   float64\n",
      " 4   pop        1704 non-null   int64  \n",
      " 5   gdpPercap  1704 non-null   float64\n",
      "dtypes: float64(2), int64(2), object(2)\n",
      "memory usage: 80.0+ KB\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print(df.dtypes)\n",
    "print('-------------------------','\\n')\n",
    "print(df.info())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "区别属性与方法之间的区别：columns,shape,info.\n",
    "DataFrame类型的对象每一列的数据类型的类别必须相同，Object是一种常见的类型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 查看数据表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1703    Zimbabwe\n",
      "Name: country, dtype: object \n",
      " ------------------------------\n",
      "       country continent  year\n",
      "1699  Zimbabwe    Africa  1987\n",
      "1700  Zimbabwe    Africa  1992\n",
      "1701  Zimbabwe    Africa  1997\n",
      "1702  Zimbabwe    Africa  2002\n",
      "1703  Zimbabwe    Africa  2007\n"
     ]
    }
   ],
   "source": [
    "# 获取列子集\n",
    "country_df = df['country']\n",
    "print(country_df.tail(n=1),'\\n',\n",
    "      '------------------------------')\n",
    "\n",
    "## 获取多列数据\n",
    "subset = df[['country','continent','year']] #必须传进去一个列表\n",
    "print(subset.tail()) #默认输出后5行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "country      Afghanistan\n",
      "continent           Asia\n",
      "year                1952\n",
      "lifeExp           28.801\n",
      "pop              8425333\n",
      "gdpPercap     779.445314\n",
      "Name: 0, dtype: object \n",
      " ------------------------------\n",
      "         country continent  year  lifeExp       pop    gdpPercap\n",
      "0    Afghanistan      Asia  1952   28.801   8425333   779.445314\n",
      "99    Bangladesh      Asia  1967   43.453  62821884   721.186086\n",
      "999     Mongolia      Asia  1967   51.253   1149500  1226.041130 \n",
      " ------------------------------\n",
      "country        Zimbabwe\n",
      "continent        Africa\n",
      "year               2007\n",
      "lifeExp          43.487\n",
      "pop            12311143\n",
      "gdpPercap    469.709298\n",
      "Name: 1703, dtype: object\n",
      "(1704, 6)\n",
      "1704\n"
     ]
    }
   ],
   "source": [
    "print(df.loc[0],'\\n',\n",
    "      '------------------------------')\n",
    "print(df.loc[[0,99,999]],'\\n',\n",
    "      '------------------------------')\n",
    "print(df.iloc[-1]) #df.loc[-1]会引发一个错误，因为数据中实际并不存在‘-1’这个标签\n",
    "\n",
    "print(df.shape)\n",
    "print(df.shape[0]) #获取元组中第一个属性值：即为行数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "range(0, 3)\n",
      "<class 'range'>\n"
     ]
    }
   ],
   "source": [
    "## 切片\n",
    "subset_series = df.loc[:,['country','continent','year']]\n",
    "# subset_error = df.loc[:,[:3]] #这个写法是错误的,包括df.loc[:,:3]\n",
    "# subset_iloc = df.iloc[:,[range(3)]] #出错,为什么？:<class 'range'>\n",
    "print(range(3))\n",
    "print(type(range(3)))\n",
    "subset_range = df.iloc[:,list(range(3))] #正确\n",
    "subset = df.iloc[:,[0,1,2]]\n",
    "subset_an = df.iloc[:,:3] #成立\n",
    "subset2 = df.iloc[:,[x for x in range(3)]]\n",
    "# subset_wrong = df.iloc[:,['country','continent','year']] #这个也是错误用法\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.series.Series'>\n",
      "<class 'pandas.core.frame.DataFrame'>\n"
     ]
    }
   ],
   "source": [
    "##!重要提醒\n",
    "subset_loc = df.loc[0]\n",
    "sub_head = df.head(n=1) #这里的参数n也可以选取负值，与列表的效果类似\n",
    "\n",
    "print(type(subset_loc)) #<class 'pandas.core.series.Series'>\n",
    "print(type(sub_head)) #<class 'pandas.core.frame.DataFrame'>\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "索引标签与行号：\n",
    "loc与iloc，在默认情况下：\n",
    "DataFrame会使用行号来替代索引标签，但是在处理时间序列数据时，索引标签将是时间戳。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       country continent  year  lifeExp       pop   gdpPercap\n",
      "0  Afghanistan      Asia  1952   28.801   8425333  779.445314\n",
      "1  Afghanistan      Asia  1957   30.332   9240934  820.853030\n",
      "2  Afghanistan      Asia  1962   31.997  10267083  853.100710\n",
      "3  Afghanistan      Asia  1967   34.020  11537966  836.197138\n",
      "4  Afghanistan      Asia  1972   36.088  13079460  739.981106 \n",
      " ----------------------------------\n",
      "year\n",
      "1952    49.057620\n",
      "1957    51.507401\n",
      "Name: lifeExp, dtype: float64\n",
      "<class 'pandas.core.series.Series'> \n",
      " ----------------------------------\n",
      "   year    lifeExp\n",
      "0  1952  49.057620\n",
      "1  1957  51.507401 \n",
      " ----------------------------------\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "   year  lifeExp_mean\n",
      "0  1952     49.057620\n",
      "1  1957     51.507401\n"
     ]
    }
   ],
   "source": [
    "## 分组，应用，聚合(split-apply-combine)\n",
    "print(df.head(),'\\n',\n",
    "      '----------------------------------')\n",
    "df_mean = df.groupby('year')['lifeExp'].mean() \n",
    "print(df_mean.head(2)) # 可以观察到结果中新产生的列并没有索引？\n",
    "print(type(df_mean),'\\n',\n",
    "      '----------------------------------')  #<class 'pandas.core.series.Series'>\n",
    "df_reset_index = df_mean.reset_index()\n",
    "print(df_reset_index.head(2),'\\n',\n",
    "      '----------------------------------')\n",
    "print(type(df_reset_index)) #<class 'pandas.core.frame.DataFrame'>\n",
    "df_reset_index.columns = ['year','lifeExp_mean']\n",
    "print(df_reset_index.head(2))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                  lifeExp     gdpPercap\n",
      "continent year                         \n",
      "Africa    1952  39.135500   1252.572466\n",
      "          1957  41.266346   1385.236062\n",
      "          1962  43.319442   1598.078825\n",
      "          1967  45.334538   2050.363801\n",
      "          1972  47.450942   2339.615674\n",
      "          1977  49.580423   2585.938508\n",
      "          1982  51.592865   2481.592960\n",
      "          1987  53.344788   2282.668991\n",
      "          1992  53.629577   2281.810333\n",
      "          1997  53.598269   2378.759555\n",
      "          2002  53.325231   2599.385159\n",
      "          2007  54.806038   3089.032605\n",
      "Americas  1952  53.279840   4079.062552\n",
      "          1957  55.960280   4616.043733\n",
      "          1962  58.398760   4901.541870\n",
      "          1967  60.410920   5668.253496\n",
      "          1972  62.394920   6491.334139\n",
      "          1977  64.391560   7352.007126\n",
      "          1982  66.228840   7506.737088\n",
      "          1987  68.090720   7793.400261\n",
      "          1992  69.568360   8044.934406\n",
      "          1997  71.150480   8889.300863\n",
      "          2002  72.422040   9287.677107\n",
      "          2007  73.608120  11003.031625\n",
      "Asia      1952  46.314394   5195.484004\n",
      "          1957  49.318544   5787.732940\n",
      "          1962  51.563223   5729.369625\n",
      "          1967  54.663640   5971.173374\n",
      "          1972  57.319269   8187.468699\n",
      "          1977  59.610556   7791.314020\n",
      "          1982  62.617939   7434.135157\n",
      "          1987  64.851182   7608.226508\n",
      "          1992  66.537212   8639.690248\n",
      "          1997  68.020515   9834.093295\n",
      "          2002  69.233879  10174.090397\n",
      "          2007  70.728485  12473.026870\n",
      "Europe    1952  64.408500   5661.057435\n",
      "          1957  66.703067   6963.012816\n",
      "          1962  68.539233   8365.486814\n",
      "          1967  69.737600  10143.823757\n",
      "          1972  70.775033  12479.575246\n",
      "          1977  71.937767  14283.979110\n",
      "          1982  72.806400  15617.896551\n",
      "          1987  73.642167  17214.310727\n",
      "          1992  74.440100  17061.568084\n",
      "          1997  75.505167  19076.781802\n",
      "          2002  76.700600  21711.732422\n",
      "          2007  77.648600  25054.481636\n",
      "Oceania   1952  69.255000  10298.085650\n",
      "          1957  70.295000  11598.522455\n",
      "          1962  71.085000  12696.452430\n",
      "          1967  71.310000  14495.021790\n",
      "          1972  71.910000  16417.333380\n",
      "          1977  72.855000  17283.957605\n",
      "          1982  74.290000  18554.709840\n",
      "          1987  75.320000  20448.040160\n",
      "          1992  76.945000  20894.045885\n",
      "          1997  78.190000  24024.175170\n",
      "          2002  79.740000  26938.778040\n",
      "          2007  80.719500  29810.188275 \n",
      " ----------------------------------\n",
      "                  lifeExp    gdpPercap\n",
      "continent year                        \n",
      "Africa    1952  39.135500  1252.572466\n",
      "          1957  41.266346  1385.236062\n",
      "          1962  43.319442  1598.078825\n",
      "          1967  45.334538  2050.363801\n",
      "          1972  47.450942  2339.615674\n"
     ]
    }
   ],
   "source": [
    "multi_group_var = df.groupby(['continent','year'])\\\n",
    "    [['lifeExp','gdpPercap']].mean()\n",
    "\n",
    "# #向这条语句后面分组的列表中加入“country”，但是结果却并没有任何变化？\n",
    "# df.groupby(['continent','year'])\\\n",
    "#     [['lifeExp','gdpPercap']].mean()\n",
    "# --> [['country','lifeExp','gdpPercap']]\n",
    "\n",
    "print(multi_group_var,'\\n',\n",
    "      '----------------------------------')\n",
    "# print(type(multi_group_var))\n",
    "\n",
    "print(multi_group_var.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "continent\n",
      "Africa      52\n",
      "Americas    25\n",
      "Asia        33\n",
      "Europe      30\n",
      "Oceania      2\n",
      "Name: country, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(df.groupby('continent')['country'].nunique())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "continent  country    \n",
      "Africa     Algeria        12\n",
      "           Angola         12\n",
      "           Libya          12\n",
      "           Ghana          12\n",
      "           Guinea         12\n",
      "                          ..\n",
      "Europe     Germany        12\n",
      "           Greece         12\n",
      "           Hungary        12\n",
      "Oceania    Australia      12\n",
      "           New Zealand    12\n",
      "Name: count, Length: 142, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(df.groupby('continent')['country'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "env_py38",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
